﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NQueries.TestSupport;
using NQueries.Utils;

namespace NQueries.Data.Test.Utils
{
    [TestClass]
    public class TypeExtensionsTest
    {
        public TestContext TestContext { get; set; }

        [TestMethod]
        public void GetPrimaryKeyPropertyInfoTest()
        {
            Assert.IsNotNull(typeof(Entity).GetPrimaryKeyPropertyInfo());
            Assert.AreEqual("Id", typeof(Entity).GetPrimaryKeyPropertyInfo().Name);
            TestTools.AssertThrows<InvalidOperationException>(() => Assert.IsNull(typeof(NonEntity).GetPrimaryKeyPropertyInfo()));
        }

        [TestMethod]
        public void HasIdPropertyTest()
        {
            Assert.IsTrue(typeof(EntityWithId).HasIdProperty());
            Assert.IsFalse(typeof(EntityWithoutId).HasIdProperty());
        }

        [TestMethod]
        public void IsCollectionWithIdsTest()
        {
            Assert.IsFalse(typeof(Entity).IsCollectionWithIds());
            Assert.IsFalse(typeof(IEnumerable<EntityWithoutId>).IsCollectionWithIds());
            Assert.IsTrue(typeof(IEnumerable<EntityWithId>).IsCollectionWithIds());
        }

        [TestMethod]
        public void IsEntityTest1()
        {
            Assert.IsTrue(typeof(Entity).IsEntity());
            Assert.IsFalse(typeof(NonEntity).IsEntity());
        }

        [TestMethod]
        public void IsEntityTest2()
        {
            Assert.IsTrue(new Entity().IsEntity());
            Assert.IsFalse(new NonEntity().IsEntity());
        }

        [TestMethod]
        public void IsEnumerableWithEntitiesTest1()
        {
            Assert.IsTrue(typeof(IEnumerable<Entity>).IsEnumerableWithEntities());
            Assert.IsFalse(typeof(IEnumerable<NonEntity>).IsEnumerableWithEntities());
            Assert.IsFalse(typeof(Entity).IsEnumerableWithEntities());
            Assert.IsTrue(typeof(Entity[]).IsEnumerableWithEntities());
            Assert.IsFalse(typeof(NonEntity[]).IsEnumerableWithEntities());
        }

        [TestMethod]
        public void IsEnumerableWithEntitiesTest2()
        {
            Assert.IsTrue(new List<Entity>().IsEnumerableWithEntities());
            Assert.IsFalse(new List<NonEntity>().IsEnumerableWithEntities());
            Assert.IsTrue(new Entity[0].IsEnumerableWithEntities());
            Assert.IsFalse(new NonEntity[0].IsEnumerableWithEntities());
        }

        #region Nested type: Entity

        [Entity]
        public class Entity
        {
            [Key]
            public Guid Id { get; set; }
        }

        #endregion

        #region Nested type: EntityWithId

        public class EntityWithId
        {
            [Key]
            public Guid Id { get; set; }

            public string NotId { get; set; }
        }

        #endregion

        #region Nested type: EntityWithoutId

        public class EntityWithoutId
        {
            public Guid Id { get; set; }

            public string NotId { get; set; }
        }

        #endregion

        #region Nested type: NonEntity

        public class NonEntity
        {
            public Guid Id { get; set; }
        }

        #endregion
    }
}